﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Peak.Core;
using Peak.Core.DataInterfaces;

namespace Peak.ApplicationServices.Services
{
  public class UserService : IUserService
  {
    private readonly IUserRepository _userRepository;
    
    public UserService(IUserRepository userRepository)
    {
      _userRepository = userRepository;
    }    

    public bool ValidateUser(string userName, string password)
    {
      if (String.IsNullOrEmpty(userName)) 
        throw new ArgumentException("Value cannot be null or empty.", "userName");
      if (String.IsNullOrEmpty(password)) 
        throw new ArgumentException("Value cannot be null or empty.", "password");
      
      User usr = _userRepository.GetByUserName(userName);
      if (usr == null || usr.IsLockedOut)
        return false;

      if (usr.Password == User.EncodePassword(password))
      {
        usr.LastLoginDate = DateTime.Now;
        return true;        
      }
      else
      {
        return false;
      }
    }        

    public CreateUserStatus CreateUser(string userName, string password, string email)
    {
      if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
      if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
      if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");

      if (_userRepository.GetByUserName(userName) != null)
        return CreateUserStatus.DuplicateUserName;

      if (_userRepository.GetByEmail(email) != null)
        return CreateUserStatus.DuplicateEmail;

      User user = new User();
      user.UserName = userName;
      user.SetPassword(password);
      user.Email = email;

      _userRepository.SaveOrUpdate(user);
      return CreateUserStatus.Success;
    }

    public bool ChangePassword(string userName, string oldPassword, string newPassword)
    {
      if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
      if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("Value cannot be null or empty.", "oldPassword");
      if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("Value cannot be null or empty.", "newPassword");

      // The underlying ChangePassword() will throw an exception rather
      // than return false in certain failure scenarios.
      try
      {
        User user = _userRepository.GetByUserName(userName);
        if (user == null || User.EncodePassword(oldPassword) != user.Password)
        {
          return false;
        }

        user.SetPassword(newPassword);
        return true;
      }
      catch (Exception)
      {
        return false;
      }
    }

    public User Get(string userName)
    {
      return _userRepository.GetByUserName(userName);
    }  
  }
}
